<template>
  <div>
    <template v-for="(item, index) in chartArr">
      <div
        v-if="isShow"
        v-show="!isNoData && item"
        :id="`${chartId}_${index}`"
        :key="index"
        class="visual_chart"
        :style="getChartItemStyle(index)"
      >
      </div>
    </template>
  </div>
</template>

<script>
import renderChartBase from '@/mixin/render-chart-base.js';
import * as echarts from 'echarts';
import { nextTick, shallowRef } from 'vue';
import { getChartProperty } from './chart-option';

export default {
  mixins: [renderChartBase],
  props: ['w', 'h', 'isShow', 'isLoading', 'isNoData', 'config', 'widgetInstanceId'],
  emits: ['chartClick'],
  data() {
    return {
      axisColor: '#ccc',
      property: null,

      chartId: 'chartId',
      is1366: false,
      quotaChartW: 0,
      quotaChartH: 0,
      chart: null,
      chart1: null,
      data: null,
      chartNum: 1,
      chartObj: {},
      chartArr: [0, 0, 0, 0, 0, 0, 0, 0],
      isBlank: true,
    };
  },
  watch: {
    w() {
      this.resizeChart();
    },
    h() {
      this.resizeChart();
    },
  },
  created() {
    this.is1366 = document.body.clientWidth <= 1366;
    this.chartId = `${this.chartId}_${this.widgetInstanceId}`;
  },
  mounted() {
    nextTick(() => {
      this.quotaChartW = document.getElementById(`chartMain${this.widgetInstanceId}`).offsetWidth;
      this.quotaChartH = document.getElementById(`chartMain${this.widgetInstanceId}`).offsetHeight;
    });
  },
  methods: {
    clearChart() {
      Object.entries(this.chartObj).map(([key]) => {
        // 移除点击事件
        this.chartObj[key] && this.chartObj[key].off('click');
        this.chartObj[key] && this.chartObj[key].dispose();
        this.chartObj[key] = null;
      });
    },
    chartClick(params) {
      this.$emit('chartClick', params);
    },

    // 生成图表
    generateChart(datas, property, configData) {
      this.$parent.chartIsCreated = false;
      const empty = !this.quotaChartW && !this.quotaChartH; // 隐藏组件时
      if (!empty && (!this.quotaChartW || !this.quotaChartH || this.quotaChartW <= 100)) {
        this.getQuotaChartWAndQuotaChartH();
        setTimeout(() => {
          this.generateChart(datas, property, configData);
        }, 100);
        return;
      }
      this.property = property;
      this.clearChart();
      this.chartObj = {};
      const self = this;

      // 渲染后生成图表  (每次dispose会不会有性能问题？)
      nextTick(() => {
        if (datas) {
          const chartNum = datas.length; // 或者从配置中取
          this.chartNum = chartNum;

          // 反向渲染图表  靠近x轴的为y0（最后一个渲染）
          this.chartArr = this.chartArr.map(n => 0);
          datas.reverse().forEach( async(dataItem, index) => {
            this.chartArr[index] = 1;
            const chart = shallowRef(echarts.init(document.getElementById(`${this.chartId}_${index}`)));
            this.chartObj[`chart_${index}`] = chart;

            const dataProperty = getChartProperty(property, chartNum - 1 - index);

            const { setChartOption } = await import(`@/components/${dataProperty.chartType}/chart-option.js`);

            // 是否是最后一个
            const isLast = index === chartNum - 1;
            const isFirst = index === 0;
            const { isMarklineShow, hasMarkLine, markLine } = dataProperty;
            const marklineConfig = { isMarklineShow, hasMarkLine, markLine };

            // 额外的配置项，需要别的组件的方法支持
            const extraConfig = {
              isLast,
              marklineConfig,
            };
            if (!isLast) {
              dataProperty.padding.bottom = dataProperty.chartPadding;
            }
            const option = setChartOption(dataItem, dataProperty, configData, extraConfig);

            option.yAxis.nameGap = 0;
            option.yAxis.nameRotate = 90;
            option.yAxis.nameTextStyle = {
              ...option.yAxis.nameTextStyle,
              align: 'right',
              padding: [0, 0, dataProperty.yAxisNameLeft * 2, 0],
            };
            if (option.yAxis.name) {
              option.grid.top -= 30;
            }
            option.grid.top += 10;

            // 隐藏原生tooltip
            if (this.property.tooltip && this.property.tooltip.isOriginVisiable === false) {
              option.tooltip.showContent = false;
            }

            this.chartObj[`chart_${index}`].setOption(option);
            this.resizeChart();
            this.chartObj[`chart_${index}`].on('click', params => {
              this.isBlank = false;
              this.chartClick(params);
            });
            const fn = params => {
              let i = 0;
              Object.entries(this.chartObj).map(([key]) => {
                if (i === this.chartNum - 1) {
                  return;
                }
                this.chartObj[`chart_${i}`].dispatchAction({
                  type: 'dataZoom',
                  start: params.start,
                  end: params.end,
                });
                i++;
              });
            };

            if (index === this.chartNum - 1) {
              this.chartObj[`chart_${index}`].on('datazoom', params => {
                fn(params);
              });
            }
          });
        }
        this.$parent.chartIsCreated = true;

        // 点击空白处传空值
        this.emitBlankVal();
      });
    },
    getQuotaChartWAndQuotaChartH() {
      this.quotaChartW = document.getElementById(`chartMain${this.widgetInstanceId}`).offsetWidth;

      const componentHeight = document.getElementById(`chartMain${this.widgetInstanceId}`).offsetHeight;
      const title = document.querySelector(`#chartMain${this.widgetInstanceId} .component-title`);
      const titleHeight = (title && title.offsetHeight) || 0;
      this.quotaChartH = componentHeight - titleHeight;
    },
    resizeChart() {
      // 延迟执行，不然有可能会获取到原来的宽高，图表不重新渲染
      setTimeout(() => {
        this.getQuotaChartWAndQuotaChartH();
        nextTick(() => {
          Object.entries(this.chartObj).map(([key]) => {
            this.chartObj[key] && this.chartObj[key].resize && this.chartObj[key].resize();
          });
        });
      }, 50);
    },
    getChartItemStyle(index) {
      const { bottom } = this.config.config.property.padding; // 下轴边距
      const { chartPadding } = this.config.config.property; // 图表间距
      const bottomDiff = bottom - chartPadding;

      const chartLen = this.chartArr.filter(n => n).length;
      let chartH = (this.quotaChartH - bottomDiff) / chartLen;
      if (index === chartLen - 1) {
        // 最后一个图标需要比前面的图标间距大一些，防止被高度挤压，跟别的图标高度不统一
        chartH = chartH + bottomDiff;
      }
      return {
        width: `${this.quotaChartW}px`,
        height: `${chartH}px`,
      };
    },
  },
};
</script>
<style lang="less"></style>
